using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace IISLogs
{
    public static class ClipboardHelper
    {
        [DllImport("user32.dll")]
        public static extern bool OpenClipboard(IntPtr hWndNewOwner);

        [DllImport("user32.dll")]
        public static extern bool CloseClipboard();

        [DllImport("user32.dll")]
        public static extern IntPtr GetClipboardData(uint uFormat);

        [DllImport("kernel32.dll")]
        public static extern IntPtr GlobalLock(IntPtr hMem);

        [DllImport("kernel32.dll")]
        public static extern bool GlobalUnlock(IntPtr hMem);

        private const uint CF_TEXT = 1;

        private static string WinGetText()
        {
            if (!OpenClipboard(IntPtr.Zero)) return string.Empty;
            var handle = GetClipboardData(CF_TEXT);
            if (handle == IntPtr.Zero)
            {
                CloseClipboard();
                return string.Empty;
            }
            var ptr = GlobalLock(handle);
            if (ptr == IntPtr.Zero)
            {
                CloseClipboard();
                return string.Empty;
            }
            string text = Marshal.PtrToStringAnsi(ptr);
            GlobalUnlock(handle);
            CloseClipboard();
            return text;
        }

        public static string GetText()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                try
                {
                    return WinGetText();
                }
                catch
                {
                    return "";
                }
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                // macOS: pbpaste
                return RunShell("pbpaste");
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                // Linux: xclip/xsel
                var result = RunShell("xclip -selection clipboard -o");
                if (!string.IsNullOrEmpty(result)) return result;
                return RunShell("xsel --clipboard --output");
            }
            return "";
        }

        private static string RunShell(string cmd)
        {
            try
            {
                using var p = new Process
                {
                    StartInfo = new ProcessStartInfo
                    {
                        FileName = "/bin/bash",
                        Arguments = $"-c \"{cmd}\"",
                        RedirectStandardOutput = true,
                        UseShellExecute = false,
                        CreateNoWindow = true
                    }
                };
                p.Start();
                string output = p.StandardOutput.ReadToEnd();
                p.WaitForExit();
                return output;
            }
            catch
            {
                return "";
            }
        }
    }
}